Skip to content

Add policy client and protocol plumbing#38514

Open
dsa0x wants to merge 1 commit into
mainfrom
policy-pr1-foundation
Open

Add policy client and protocol plumbing#38514
dsa0x wants to merge 1 commit into
mainfrom
policy-pr1-foundation

Conversation

@dsa0x
Copy link
Copy Markdown
Member

@dsa0x dsa0x commented May 4, 2026

This is part of a stacked series to upstream the policy work in smaller, reviewable pieces:

This PR introduces the policy package and the basic protocol/client plumbing that the rest of the stack builds on.
The goal here is to land the policy-specific infrastructure first so the later PRs can focus on runtime behavior.

Included here

  • policy client setup and implementation
  • RPC protocol types,
  • policy diagnostics/types
  • callback service plumbing
  • generated protobufs
  • protobuf compile tool updates

Target Release

1.16.x

Rollback Plan

  • If a change needs to be reverted, we will roll out an update to the code within 7 days.

Changes to Security Controls

Are there any changes to security controls (access controls, encryption, logging) in this pull request? If so, explain.

CHANGELOG entry

  • This change is user-facing and I added a changelog entry.
  • This change is not user-facing.

@dsa0x dsa0x added the no-changelog-needed Add this to your PR if the change does not require a changelog entry label May 4, 2026
@dsa0x dsa0x marked this pull request as ready for review May 18, 2026 09:52
@dsa0x dsa0x requested a review from a team as a code owner May 18, 2026 09:52
Copy link
Copy Markdown
Member

@SarahFrench SarahFrench left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👋🏻 I've been taking a look at this today and will resume tomorrow, but here are some initial comments that mainly revolve around testing.

}

func RegisterCallbackServiceServer(s grpc.ServiceRegistrar, srv CallbackServiceServer) {
// If the following call pancis, it indicates UnimplementedCallbackServiceServer was
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// If the following call pancis, it indicates UnimplementedCallbackServiceServer was
// If the following call panics, it indicates UnimplementedCallbackServiceServer was

Comment thread internal/policy/client.go
}
}

func (c *client) Evaluate(ctx context.Context, req EvaluationRequest[*proto.ResourceMetadata]) EvaluationResponse {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given the existence of EvaluateModule and EvaluateProvider, what do you think about renaming this EvaluateResource? I think this would make the code resemble the proto definition, too.

return s.evaluateModuleFn(req)
}

func TestClientEvaluate(t *testing.T) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think there can be more test coverages here, both for this and the other 2 Evaluate-type methods.

For example:

  • You could have the evaluateResourceFn return an empty or nil response alongside a non-nil error - does the response from Evaluate handle that error as expected?
  • You could also include more data in the response from evaluateResourceFn and make more assertions about how it's transformed by the Evaluate method. E.g. if you include some PolicyDetails data and assert that diagnostics from in there are transformed as expected into diagnostics in the response from Evaluate.

return diags
}

func (diagnostic *Diagnostic) ToHCL() *hcl.Diagnostic {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could this benefit from some test coverage?

I know the concept of 'diagnostic extras' isn't new to the codebase, but this implementation is and it might be worth adding some light tests asserting that these behave in the way we expect.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

➕ to that idea, I was also looking at the proto definition of diagnostic and it's a little difficult to understand exactly what data we will receive in a diagnostic. Perhaps some tests could serve as documentation of "these are some examples of what this extra info will look like"

}, nil
},
},
callbackRegistry: callback.NewRegistry(),
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Idea: could you make a mock callback registry to use in tests like this?

Copy link
Copy Markdown
Member

@austinvalle austinvalle left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very nice 👍🏻, I appreciate you breaking these out 😆. I left some comments and questions!


message GetResourcesRequest {
string type = 1;
bytes data = 2;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: This is a little generic for the name, I believe the data is a filter object so perhaps filter would be more descriptive? 😅


message GetDataSourceRequest {
string type = 1;
bytes data = 2;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: similar to the above, maybe this could be config?

uint32 evaluation_request_id = 3;
}

message GetResourcesResponse {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we also return diagnostics from this?

uint32 evaluation_request_id = 3;
}

message GetDataSourceResponse {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

similar to above, should we also return diagnostics from this?

message Step {
oneof step {
string attribute = 1;
bytes index = 2;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this a cty value that could be a string or number? 👀

Comment on lines +186 to +187
// module_source is the source for the module that is used (e.g., "./modules/s3_bucket")
string module_source = 1;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Is this needed since the source is also defined in ModuleMetadata? (or perhaps it can be removed from that shared type)

Comment on lines +63 to +64
string source = 1;
string version = 2;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm assuming source and version are guaranteed to be evaluated at this point? So we don't need to worry about the recent dynamic module sourcing work impacting this 👀

Comment on lines +177 to +178
default:
panic(fmt.Errorf("unsupported Step type: %T", step))
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Does this method need an error return if we're going to panic here anyways 👀 (similar question to the above ToCtyPath)

Comment on lines +135 to +136
Start: rng.Start.ToHclPos(),
End: rng.End.ToHclPos(),
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are these guaranteed to be non-nil? 👀

Comment thread internal/policy/result.go
Comment on lines +36 to +37
// should be exhaustive
panic("unhandled EvaluateResult")
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// should be exhaustive
panic("unhandled EvaluateResult")
// should be exhaustive
panic(fmt.Errorf("unhandled EvaluateResult type: %T", result))

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

no-changelog-needed Add this to your PR if the change does not require a changelog entry

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants